// ============================================================================
// RabbitMQ 管理器 - 处理消息队列操作
// ============================================================================

import { RabbitMQClient, WorkQueue, createFunctionHandler } from '@roasmax/rabbitmq'
import { DEFAULT_APP_CONFIG } from '../../shared/constants'
import { logger } from '@roasmax/logger'
import { WeiboLoginData } from '../../shared/types'

/**
 * RabbitMQ 管理器类
 */
export class RabbitMQManager {
  private static instance: RabbitMQManager
  private client: RabbitMQClient | null = null
  private workQueue: WorkQueue | null = null
  private weiboDataQueue: WorkQueue | null = null
  private weiboDetailQueue: WorkQueue | null = null
  private weiboAccountQueue: WorkQueue | null = null;
  private scheduledTaskQueue: WorkQueue | null = null
  private isInitialized = false

  private constructor() { }

  /**
   * 获取单例实例
   */
  static getInstance(): RabbitMQManager {
    if (!RabbitMQManager.instance) {
      RabbitMQManager.instance = new RabbitMQManager()
    }
    return RabbitMQManager.instance
  }

  /**
   * 初始化RabbitMQ连接
   */
  async initialize(): Promise<void> {
    try {
      if (this.isInitialized) {
        logger.debug('RabbitMQ已经初始化')
        return
      }

      const config = DEFAULT_APP_CONFIG.rabbitmq

      // 创建客户端
      this.client = RabbitMQClient.create({
        host: config.host,
        port: config.port,
        username: config.username,
        password: config.password
      })

      // 初始化连接
      await this.client.initialize()

      // 创建工作队列
      this.workQueue = this.client.createWorkQueue(config.queues.loginSuccess)
      await this.workQueue.setupQueue()

      // 创建微博数据队列
      this.weiboDataQueue = this.client.createWorkQueue(config.queues.weiboData)
      await this.weiboDataQueue.setupQueue()

      // 创建微博详情队列
      this.weiboDetailQueue = this.client.createWorkQueue(config.queues.weiboDetail)
      await this.weiboDetailQueue.setupQueue()

      this.weiboAccountQueue = this.client.createWorkQueue(config.queues.weiboAccount)
      await this.weiboAccountQueue.setupQueue()

      // 创建定时任务队列
      this.scheduledTaskQueue = this.client.createWorkQueue(config.queues.scheduledTask)
      await this.scheduledTaskQueue.setupQueue()

      this.isInitialized = true
      logger.info('RabbitMQ初始化成功', {
        host: config.host,
        port: config.port,
        queues: {
          loginSuccess: config.queues.loginSuccess,
          weiboData: config.queues.weiboData,
          weiboDetail: config.queues.weiboDetail,
          scheduledTask: config.queues.scheduledTask
        }
      })
    } catch (error) {
      logger.error('RabbitMQ初始化失败', error)
      throw error
    }
  }

  /**
   * 发送登录成功消息
   */
  async sendLoginSuccessMessage(loginData: WeiboLoginData): Promise<void> {
    try {
      if (!this.isInitialized || !this.workQueue) {
        logger.warn('RabbitMQ未初始化，跳过发送消息')
        return
      }
      await this.workQueue.sendTask(loginData)
    } catch (error) {
      logger.error('发送登录成功消息失败', error)
    }
  }

  /**
   * 发送用户信息更新消息
   */
  async sendUserInfoUpdateMessage(userInfo: any): Promise<void> {
    try {
      if (!this.isInitialized || !this.workQueue) {
        logger.warn('RabbitMQ未初始化，跳过发送消息')
        return
      }

      const message = {
        type: 'user_info_update',
        timestamp: new Date().toISOString(),
        userInfo
      }

      await this.workQueue.sendTask(message)

      logger.info('用户信息更新消息已发送到MQ', {
        uid: userInfo.uid,
        nickname: userInfo.nickname
      })
    } catch (error) {
      logger.error('发送用户信息更新消息失败', error)
    }
  }

  /**
   * 发送微博详情数据消息
   */
  async sendWeiboDetailMessage(weiboData: any): Promise<void> {
    try {
      if (!this.isInitialized || !this.weiboDetailQueue) {
        logger.warn('RabbitMQ未初始化或微博详情队列不可用，跳过发送消息')
        return
      }

      const message = {
        type: 'weibo_detail',
        timestamp: new Date().toISOString(),
        data: weiboData
      }

      await this.weiboDetailQueue.sendTask(message)

      logger.info('微博详情消息已发送到MQ', {
        weiboId: weiboData.id || weiboData.mid,
        userId: weiboData.user?.id,
        queueName: DEFAULT_APP_CONFIG.rabbitmq.queues.weiboDetail
      })
    } catch (error) {
      logger.error('发送微博详情消息失败', error)
      // 不抛出错误，避免影响爬取流程
    }
  }

  async sendWeiboAccountMessage(accountData: any): Promise<void> {
    try {
      if (!this.isInitialized || !this.weiboAccountQueue) {
        return
      }

      const message = {
        type: 'weibo_account',
        timestamp: new Date().toISOString(),
        data: accountData
      }

      await this.weiboAccountQueue.sendTask(message)
    } catch (error) {
      // 不抛出错误，避免影响爬取流程
    }
  }

  /**
   * 批量发送微博详情数据消息
   */
  async sendBatchWeiboDetailMessages(weiboDataList: any[]): Promise<void> {
    if (!weiboDataList || weiboDataList.length === 0) {
      logger.warn('微博数据列表为空，跳过批量发送')
      return
    }

    try {
      if (!this.isInitialized || !this.weiboDetailQueue) {
        logger.warn('RabbitMQ未初始化或微博详情队列不可用，跳过批量发送消息')
        return
      }

      const batchMessage = {
        type: 'weibo_detail_batch',
        timestamp: new Date().toISOString(),
        count: weiboDataList.length,
        data: weiboDataList
      }

      await this.weiboDetailQueue.sendTask(batchMessage)

      logger.info('批量微博详情消息已发送到MQ', {
        count: weiboDataList.length,
        queueName: DEFAULT_APP_CONFIG.rabbitmq.queues.weiboDetail
      })
    } catch (error) {
      logger.error('批量发送微博详情消息失败', error)

      // 如果批量发送失败，尝试逐个发送
      logger.info('尝试逐个发送微博详情消息')
      for (const weiboData of weiboDataList) {
        try {
          await this.sendWeiboDetailMessage(weiboData)
          // 添加延迟避免过快发送
          await new Promise(resolve => setTimeout(resolve, 100))
        } catch (individualError) {
          logger.error('逐个发送微博详情消息失败', {
            weiboId: weiboData.id || weiboData.mid,
            error: individualError
          })
        }
      }
    }
  }

  /**
   * 发送定时任务状态消息
   */
  async sendScheduledTaskMessage(taskData: any): Promise<void> {
    try {
      if (!this.isInitialized || !this.scheduledTaskQueue) {
        logger.warn('RabbitMQ未初始化或定时任务队列不可用，跳过发送消息')
        return
      }

      const message = {
        type: 'scheduled_task_status',
        timestamp: new Date().toISOString(),
        taskData
      }

      await this.scheduledTaskQueue.sendTask(message)

      logger.info('定时任务状态消息已发送到MQ', {
        taskId: taskData.taskId,
        status: taskData.status,
        queueName: DEFAULT_APP_CONFIG.rabbitmq.queues.scheduledTask
      })
    } catch (error) {
      logger.error('发送定时任务状态消息失败', error)
    }
  }

  /**
   * 关闭连接
   */
  async close(): Promise<void> {
    try {
      if (this.client) {
        await this.client.close()
        this.client = null
        this.workQueue = null
        this.weiboDataQueue = null
        this.weiboDetailQueue = null
        this.scheduledTaskQueue = null
        this.isInitialized = false
        logger.info('RabbitMQ连接已关闭')
      }
    } catch (error) {
      logger.error('关闭RabbitMQ连接失败', error)
    }
  }

  /**
   * 检查连接状态
   */
  isConnected(): boolean {
    return this.isInitialized && this.client !== null
  }
}

/**
 * 全局RabbitMQ管理器实例
 */
export const rabbitmqManager = RabbitMQManager.getInstance()
